package com.eastfair.config.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.eastfair.boot.service.SuperCacheServiceImpl;
import com.eastfair.cache.configattribute.AttachmentCacheKeyBuilder;
import com.eastfair.config.dao.AttachmentMapper;
import com.eastfair.config.dto.AttachmentDTO;
import com.eastfair.config.entity.Attachment;
import com.eastfair.config.service.AttachmentService;
import com.eastfair.config.vo.AttachmentVO;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.model.CacheKeyBuilder;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.core.utils.StringUtils;
import com.eastfair.projectcore.api.ProjectCoreServiceFeign;import com.eastfair.core.snowflake.DefaultUidGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 附件资源管理
 * </p>
 *
 * @author zjn
 * @date 2021-08-31
 */
@Slf4j
@Service
@DS("#thread.tenant")
public class AttachmentServiceImpl extends SuperCacheServiceImpl<AttachmentMapper, Attachment> implements AttachmentService {

    @Autowired
    private ProjectCoreServiceFeign projectCoreServiceFeign;

    /**************sharding 分库分表操作 *****************/
    @Override
    public boolean updateByIdOfShard(Attachment entity) {
        UpdateWrapper<Attachment> updateWrapper = new UpdateWrapper<>();
        //可将指定字段更新为null
        updateWrapper.lambda().eq(Attachment::getProjectId, ContextUtil.getProjectId()).eq(Attachment::getId, entity.getId());
        entity.setProjectId(null);
        //删除缓存
        delCache(entity);
        return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));
    }

    @Override
    protected CacheKeyBuilder cacheKeyBuilder() {
        return new AttachmentCacheKeyBuilder();
    }

    /**
     * 处理新增相关处理
     *
     * @param model 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerSave(Attachment model) {
        //雪花ID
        model.setId(DefaultUidGenerator.getUidOfProjectId(ContextUtil.getProjectId()));
        model.setProjectId(ContextUtil.getProjectId());
        return R.successDef();
    }

    @Override
    public Boolean saveAttachmentList(List<AttachmentDTO> attachmentDTOList) {
        if (attachmentDTOList == null || attachmentDTOList.isEmpty()) {
            throw new NullPointerException("params is null");
        }

        // 批量获取雪花id
        List<Long> ids = DefaultUidGenerator.getBatUidOfProjectId(ContextUtil.getProjectId(), attachmentDTOList.size());
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("System exception, generate snowflake id error");
        }

        List<Attachment> attachmentList = ConvertUtil.convertList(attachmentDTOList, Attachment.class);
        for (int i = 0; i < attachmentList.size(); i++) {
            attachmentList.get(i).setProjectId(ContextUtil.getProjectId()).setId(ids.get(i));
        }
        return saveBatch(attachmentList);
    }

    @Override
    public Boolean deleteByBusiness(AttachmentDTO attachmentDTO) {
        if (attachmentDTO == null || attachmentDTO.getBusinessType() == null || attachmentDTO.getBusinessId() == null) {
            throw new NullPointerException("error params, businessType or businessId is null");
        }

        // 清除缓存
        QueryWrapper<Attachment> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Attachment::getProjectId, ContextUtil.getProjectId()).eq(Attachment::getBusinessType, attachmentDTO.getBusinessType())
                .eq(Attachment::getBusinessId, attachmentDTO.getBusinessId()).eq(Attachment::getIsDelete, BusinessConstant.DELETE_NO);
        List<Attachment> attachmentList = list(queryWrapper);
        if (attachmentList == null || attachmentList.isEmpty()) {
            return true;
        }
        List<Long> ids = attachmentList.stream().map(Attachment::getId).collect(Collectors.toList());
        delCache(ids);

        //删除附件
        UpdateWrapper<Attachment> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(Attachment::getProjectId, ContextUtil.getProjectId()).eq(Attachment::getBusinessType, attachmentDTO.getBusinessType())
                .eq(Attachment::getBusinessId, attachmentDTO.getBusinessId()).set(Attachment::getIsDelete, BusinessConstant.DELETE_YES);
        return update(updateWrapper);
    }

    @Override
    public Boolean deleteAndSaveAttachmentList(List<AttachmentDTO> attachmentDTOList) {
        if (attachmentDTOList == null || attachmentDTOList.isEmpty()) {
            throw new NullPointerException("params is null");
        }
        // 批量删除
        deleteByBusiness(attachmentDTOList.get(0));

        // 批量新增
        return saveAttachmentList(attachmentDTOList);
    }

    @Override
    public List<AttachmentVO> getAttachmentListByBusiness(AttachmentDTO attachmentDTO) {
        if (StringUtils.isBlank(attachmentDTO.getBusinessType()) || attachmentDTO.getBusinessId() == null) {
            throw new NullPointerException("error params, businessType or businessId is null");
        }
        QueryWrapper<Attachment> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Attachment::getProjectId, ContextUtil.getProjectId()).eq(Attachment::getBusinessType, attachmentDTO.getBusinessType())
                .eq(Attachment::getBusinessId, attachmentDTO.getBusinessId()).eq(Attachment::getIsDelete, BusinessConstant.DELETE_NO)
                .eq(Attachment::getIsEnable, BusinessConstant.ENABLE_YES).orderByAsc(Attachment::getSequence);
        return ConvertUtil.convertList(list(queryWrapper), AttachmentVO.class);
    }
}
